home *** CD-ROM | disk | FTP | other *** search
/ Amiga Format CD 52 / Amiga Format AFCD52 (Issue 136, May 2000).iso / -serious- / programming / c / simplecalc / calc.clip.c < prev    next >
C/C++ Source or Header  |  2000-02-28  |  7KB  |  396 lines

  1. /* -----------------------------------------------------------
  2.   $VER: calc.clip.c 1.01 (22.02.2000)
  3.  
  4.   clipboard support for calculator project
  5.  
  6.   (C) Copyright 2000 Matthew J Fletcher - All Rights Reserved.
  7.   amimjf@connectfree.co.uk - www.amimjf.connectfree.co.uk
  8.   ------------------------------------------------------------ */
  9.  
  10. #include <exec/types.h>
  11. #include <exec/ports.h>
  12. #include <exec/io.h>
  13. #include <exec/memory.h>
  14. #include <devices/clipboard.h>
  15. #include <libraries/dosextens.h>
  16. #include <libraries/dos.h>
  17.  
  18. #include "Calc.h"
  19.  
  20. #include <clib/exec_protos.h>
  21. #include <clib/alib_protos.h>
  22.  
  23. #include <stdlib.h>
  24. #include <stdio.h>
  25. #include <string.h>
  26.  
  27. /* used structs */
  28.  
  29. struct IOClipReq *ior;
  30. struct cbbuf *buf;
  31.  
  32. /* whats on screen */
  33. extern char buffer[100];
  34.  
  35. int ReadClip(char *string)
  36. {
  37. /* Open clipboard.device unit 0 */
  38. if (ior=CBOpen(0L))
  39.     { /* Look for FTXT in clipboard */
  40.     if (CBQueryFTXT(ior))
  41.         { /* Obtain a copy of the contents of each CHRS chunk */
  42.  
  43.         while (buf=CBReadCHRS(ior))
  44.               { /* Process data */
  45.               sprintf(buffer, "%s",buf->mem);
  46.               // printf("read string, (%s)",buffer);
  47.               /* Free buffer allocated by CBReadCHRS() */
  48.               CBFreeBuf(buf);
  49.               }
  50.  
  51.         CBReadDone(ior);
  52.         } /* end if */
  53.  
  54.     else { printf("No FTXT in clipboard\n");
  55.            return(-1);
  56.          }
  57.  
  58.     CBClose(ior);
  59.     }
  60.  
  61. else { printf("Error opening clipboard unit 0\n");
  62.        return(-1);
  63.      }
  64.  
  65. return(0); /* it all went swimingly */
  66. } /* end ReadClip */
  67.  
  68.  
  69.  
  70. int WriteClip(char *string)
  71. { /* Write a string to the clipboard */
  72.  
  73. // printf("wrote string, (%s)",string);
  74. /* Open clipboard.device unit 0 */
  75. if (ior = CBOpen(0L))
  76.     {
  77.     if (!(CBWriteFTXT(ior,string)))
  78.         {
  79.         printf("Error writing to clipboard: io_Error = %ld\n",ior->io_Error);
  80.         return(-1);
  81.         }
  82.     CBClose(ior);
  83.     }
  84.  
  85. else
  86.     { printf("Error opening clipboard.device\n");
  87.       return(-1);
  88.     }
  89.  
  90. return(0);
  91. } /* end write clip */
  92.  
  93.  
  94. struct IOClipReq *CBOpen(ULONG unit)
  95. {
  96. struct MsgPort *mp;
  97. struct IOStdReq *ior;
  98.  
  99. if (mp = CreatePort(0L,0L))
  100.     {
  101.     if (ior=(struct IOStdReq *)CreateExtIO(mp,sizeof(struct IOClipReq)))
  102.         {
  103.         if (!(OpenDevice("clipboard.device",unit,ior,0L)))
  104.             {
  105.             return((struct IOClipReq *)ior);
  106.             }
  107.         DeleteExtIO(ior);
  108.         }
  109.     DeletePort(mp);
  110.     }
  111. return(NULL);
  112.  
  113. }
  114.  
  115.  
  116. void CBClose(struct IOClipReq *ior)
  117. {
  118. struct MsgPort *mp;
  119.  
  120. mp = ior->io_Message.mn_ReplyPort;
  121.  
  122. CloseDevice((struct IOStdReq *)ior);
  123. DeleteExtIO((struct IOStdReq *)ior);
  124. DeletePort(mp);
  125.  
  126. }
  127.  
  128. int CBWriteFTXT(struct IOClipReq *ior,char *string)
  129. {
  130. ULONG length, slen;
  131. BOOL odd;
  132. int success;
  133.  
  134. slen = strlen(string);
  135. odd = (slen & 1);               /* pad byte flag */
  136.  
  137. length = (odd) ? slen+1 : slen;
  138.  
  139. /* initial set-up for Offset, Error, and ClipID */
  140.  
  141. ior->io_Offset = 0;
  142. ior->io_Error  = 0;
  143. ior->io_ClipID = 0;
  144.  
  145.  
  146. /* Create the IFF header information */
  147.  
  148. WriteLong(ior, (long *) "FORM");     /* "FORM"             */
  149. length+=12L;                         /* + "[size]FTXTCHRS" */
  150. WriteLong(ior, &length);             /* total length       */
  151. WriteLong(ior, (long *) "FTXT");     /* "FTXT"             */
  152. WriteLong(ior, (long *) "CHRS");     /* "CHRS"             */
  153. WriteLong(ior, &slen);               /* string length      */
  154.  
  155. /* Write string */
  156. ior->io_Data    = (STRPTR)string;
  157. ior->io_Length  = slen;
  158. ior->io_Command = CMD_WRITE;
  159. DoIO( (struct IORequest *) ior);
  160.  
  161. /* Pad if needed */
  162. if (odd)
  163.     {
  164.     ior->io_Data   = (STRPTR)"";
  165.     ior->io_Length = 1L;
  166.     DoIO( (struct IORequest *) ior);
  167.     }
  168.  
  169. /* Tell the clipboard we are done writing */
  170.  
  171. ior->io_Command=CMD_UPDATE;
  172. DoIO( (struct IORequest *) ior);
  173.  
  174. /* Check if io_Error was set by any of the preceding IO requests */
  175. success = ior->io_Error ? FALSE : TRUE;
  176.  
  177. return(success);
  178. }
  179.  
  180. WriteLong(ior, ldata)
  181. struct IOClipReq *ior;
  182. long *ldata;
  183. {
  184.  
  185. ior->io_Data    = (STRPTR)ldata;
  186. ior->io_Length  = 4L;
  187. ior->io_Command = CMD_WRITE;
  188. DoIO( (struct IORequest *) ior);
  189.  
  190. if (ior->io_Actual == 4)
  191.     {
  192.     return( ior->io_Error ? FALSE : TRUE);
  193.     }
  194.  
  195. return(FALSE);
  196.  
  197. }
  198.  
  199.  
  200. int CBQueryFTXT(struct IOClipReq *ior)
  201. {
  202. ULONG cbuff[4];
  203.  
  204. /* initial set-up for Offset, Error, and ClipID */
  205.  
  206. ior->io_Offset = 0;
  207. ior->io_Error  = 0;
  208. ior->io_ClipID = 0;
  209.  
  210. /* Look for "FORM[size]FTXT" */
  211.  
  212. ior->io_Command = CMD_READ;
  213. ior->io_Data    = (STRPTR)cbuff;
  214. ior->io_Length  = 12;
  215.  
  216. DoIO( (struct IORequest *) ior);
  217.  
  218.  
  219. /* Check to see if we have at least 12 bytes */
  220.  
  221. if (ior->io_Actual == 12L)
  222.     {
  223.     /* Check to see if it starts with "FORM" */
  224.     if (cbuff[0] == ID_FORM)
  225.         {
  226.         /* Check to see if its "FTXT" */
  227.         if (cbuff[2] == ID_FTXT)
  228.             return(TRUE);
  229.         }
  230.  
  231.     /* It's not "FORM[size]FTXT", so tell clipboard we are done */
  232.     }
  233.  
  234. CBReadDone(ior);
  235.  
  236. return(FALSE);
  237. }
  238.  
  239.  
  240. struct cbbuf *CBReadCHRS(struct IOClipReq *ior)
  241. {
  242. ULONG chunk,size;
  243. struct cbbuf *buf;
  244. int looking;
  245.  
  246. /* Find next CHRS chunk */
  247.  
  248. looking = TRUE;
  249. buf = NULL;
  250.  
  251. while (looking)
  252.       {
  253.       looking = FALSE;
  254.  
  255.       if (ReadLong(ior,&chunk))
  256.           {
  257.           /* Is CHRS chunk ? */
  258.           if (chunk == ID_CHRS)
  259.               {
  260.               /* Get size of chunk, and copy data */
  261.               if (ReadLong(ior,&size))
  262.                   {
  263.                   if (size)
  264.                       buf=FillCBData(ior,size);
  265.                   }
  266.               }
  267.  
  268.             /* If not, skip to next chunk */
  269.           else
  270.               {
  271.               if (ReadLong(ior,&size))
  272.                   {
  273.                    looking = TRUE;
  274.                    if (size & 1)
  275.                        size++;    /* if odd size, add pad byte */
  276.  
  277.                     ior->io_Offset += size;
  278.                   }
  279.               }
  280.           }
  281.       }
  282.  
  283. if (buf == NULL)
  284.     CBReadDone(ior);        /* tell clipboard we are done */
  285.  
  286. return(buf);
  287. }
  288.  
  289.  
  290. ReadLong(ior, ldata)
  291. struct IOClipReq *ior;
  292. ULONG *ldata;
  293. {
  294. ior->io_Command = CMD_READ;
  295. ior->io_Data    = (STRPTR)ldata;
  296. ior->io_Length  = 4L;
  297.  
  298. DoIO( (struct IORequest *) ior);
  299.  
  300. if (ior->io_Actual == 4)
  301.     {
  302.     return( ior->io_Error ? FALSE : TRUE);
  303.     }
  304.  
  305. return(FALSE);
  306. }
  307.  
  308.  
  309. struct cbbuf *FillCBData(struct IOClipReq *ior,ULONG size)
  310. {
  311. register UBYTE *to,*from;
  312. register ULONG x,count;
  313.  
  314. ULONG length;
  315. struct cbbuf *buf,*success;
  316.  
  317. success = NULL;
  318.  
  319. if (buf = AllocMem(sizeof(struct cbbuf),MEMF_PUBLIC))
  320.     {
  321.  
  322.     length = size;
  323.     if (size & 1)
  324.         length++;            /* if odd size, read 1 more */
  325.  
  326.     if (buf->mem = AllocMem(length+1L,MEMF_PUBLIC))
  327.         {
  328.         buf->size = length+1L;
  329.  
  330.         ior->io_Command = CMD_READ;
  331.         ior->io_Data    = (STRPTR)buf->mem;
  332.         ior->io_Length  = length;
  333.  
  334.         to = buf->mem;
  335.         count = 0L;
  336.  
  337.         if (!(DoIO( (struct IOStdReq *) ior)))
  338.             {
  339.             if (ior->io_Actual == length)
  340.                 {
  341.                 success = buf;      /* everything succeeded */
  342.  
  343.                 /* strip NULL bytes */
  344.                 for (x=0, from=buf->mem ;x<size;x++)
  345.                      {
  346.                      if (*from)
  347.                          {
  348.                          *to = *from;
  349.                          to++;
  350.                          count++;
  351.                          }
  352.  
  353.                      from++;
  354.                      }
  355.                 *to=0x0;            /* Null terminate buffer */
  356.                 buf->count = count; /* cache count of chars in buf */
  357.                 }
  358.             }
  359.  
  360.         if (!(success))
  361.             FreeMem(buf->mem,buf->size);
  362.         }
  363.     if (!(success))
  364.         FreeMem(buf,sizeof(struct cbbuf));
  365.     }
  366.  
  367. return(success);
  368. }
  369.  
  370. void CBReadDone(struct IOClipReq *ior)
  371. {
  372. char buffer[256];
  373.  
  374. ior->io_Command = CMD_READ;
  375. ior->io_Data    = (STRPTR)buffer;
  376. ior->io_Length  = 254;
  377.  
  378.  
  379. /* falls through immediately if io_Actual == 0 */
  380.  
  381. while (ior->io_Actual)
  382.       {
  383.       if (DoIO( (struct IORequest *) ior))
  384.           break;
  385.       }
  386. }
  387.  
  388.  
  389. void CBFreeBuf(struct cbbuf *buf)
  390. {
  391. FreeMem(buf->mem, buf->size);
  392. FreeMem(buf, sizeof(struct cbbuf));
  393. }
  394.  
  395.  
  396.